
package com.csx.midware.redis;

import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;
import redis.clients.jedis.JedisPubSub;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;

/**
 * RedisPubSubExample 类展示了如何使用 Redis 的发布订阅（Pub/Sub）功能。
 * 实际应用场景包括：
 * - 实时消息通知：在聊天应用或即时通讯系统中，实时发送和接收消息。
 * - 事件驱动架构：在微服务架构中，不同服务通过发布订阅模式进行通信。
 * - 日志收集与监控：将日志或监控数据发布到特定的频道，集中处理和存储日志数据。
 * - 实时数据分析：实时处理和分析数据，进行决策。
 * - 股票行情更新：实时获取和更新股票行情信息。
 * - 游戏内通信：实时更新游戏状态。
 * - 物联网设备通信：实时处理传感器数据，进行监控和控制。
 *
 * </pre>
 */
public class RedisPubSubExample {

    private static final String HOST = "localhost";
    private static final int PORT = 6379;
    private static final String CHANNEL = "test-channel";

    private JedisPool jedisPool;
    private ExecutorService executorService;

    public RedisPubSubExample() {
        JedisPoolConfig poolConfig = new JedisPoolConfig();
        poolConfig.setMaxTotal(128);
        jedisPool = new JedisPool(poolConfig, HOST, PORT);
        executorService = Executors.newSingleThreadExecutor();
    }

    public void startSubscription() {
        executorService.submit(() -> {
            try (Jedis jedis = jedisPool.getResource()) {
                JedisPubSub jedisPubSub = new JedisPubSub() {
                    @Override
                    public void onMessage(String channel, String message) {
                        System.out.println("Received message from channel '" + channel + "': " + message);
                    }
                };
                jedis.subscribe(jedisPubSub, CHANNEL);
            } catch (Exception e) {
                e.printStackTrace();
            }
        });
    }

    public void publishMessage(String message) {
        try (Jedis jedis = jedisPool.getResource()) {
            jedis.publish(CHANNEL, message);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public void shutdown() {
        executorService.shutdown();
        try {
            if (!executorService.awaitTermination(5, TimeUnit.SECONDS)) {
                executorService.shutdownNow();
            }
        } catch (InterruptedException e) {
            executorService.shutdownNow();
        }
        jedisPool.close();
    }

    public static void main(String[] args) {
        RedisPubSubExample example = new RedisPubSubExample();
        example.startSubscription();

        // 发布消息
        example.publishMessage("Hello, Redis Pub/Sub!");
        example.publishMessage("Hello, Redis Pub/Sub2!");

        // 等待一段时间后关闭
        try {
            Thread.sleep(5000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        example.shutdown();
    }
}